#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>

#include "logman_file.h"
#include "logman_workqueue.h"
#include "logman_fifo.h"
#include "logman_timer.h"

#define DEVICE_NAME								"logman"

static dev_t devno = 0;

static struct cdev logman_cdev;
static struct class *logman_class = NULL;
static struct device *logman_device = NULL;

static int __init logman_init(void)
{
	int ret = 0;

	ret = logman_fifo_init();

	if (0 != ret) {
		printk(KERN_ERR "error logman_fifo_init\n");
		goto out;
	}

	ret = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);

	if (0 != ret) {
		printk(KERN_ERR "error alloc_chrdev_region\n");
		goto out1;
	}

	cdev_init(&logman_cdev, &logman_file_fops);
	
	logman_cdev.owner = THIS_MODULE;
	
	ret = cdev_add(&logman_cdev, devno, 1);

	if (0 != ret) {
		printk(KERN_ERR "error cdev_add\n");
		goto out1;
	}

	logman_class = class_create(THIS_MODULE, DEVICE_NAME);
	
	if(NULL == logman_class) {
		printk(KERN_ERR "error class_create\n");
		ret = -ENOMEM;
		goto out1;
	}

	logman_device = device_create(logman_class, NULL, devno, NULL, DEVICE_NAME);

	if(NULL == logman_device) {
		printk(KERN_ERR "error device_create\n");
		ret = -ENOMEM;
		goto out1;
	}
	
	logman_workqueue_init();
	
//	logman_timer_workqueue_init(logman_workqueue_wakeup, 1);

	printk(KERN_INFO "driver init success\n");
	printk(KERN_INFO "Build Time: %s, %s\n", __TIME__, __DATE__);

	return 0;

out1:
	logman_fifo_deinit();
out:
	return ret;
}

static void __exit logman_exit(void)
{
	logman_timer_workqueue_deinit();
	logman_workqueue_deinit();
	logman_fifo_deinit();

	if(NULL != logman_device) {
		device_unregister(logman_device);
		logman_device = NULL;
	}

	if(NULL != logman_class) {
		class_destroy(logman_class);
		logman_class = NULL;
	}

	cdev_del(&logman_cdev);

	printk(KERN_INFO "driver exit success\n");
}

MODULE_AUTHOR("Yan Jun");
MODULE_DESCRIPTION("collect log");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
MODULE_ALIAS("logman");

module_init(logman_init);
module_exit(logman_exit);
